﻿using System;
using System.Collections.Generic;
using System.Linq;
using LL.Business;
using NanoERP.Model;
using NanoERP.Business.BaseInfo;
using NanoERP.Common;

namespace NanoERP.Business.BillInfo
{
    /// <summary>
    /// 单据业务类
    /// </summary>
    public class BillinfoBLL : ServiceBase
    {
        /// <summary>
        /// 订单信息查询
        /// </summary>
        /// <param name="billType">单据类型</param>
        /// <param name="clientId">供应商编号</param>
        /// <param name="storageId">仓库编号</param>
        /// <param name="goodsName">商品名称</param>
        /// <param name="busiuserId">经手人</param>
        /// <param name="curphaseuserId">当前审核人</param>
        /// <param name="createuserId">创建人编号</param>
        /// <param name="billNo">订单编号</param>
        /// <param name="note2">附记</param>
        /// <param name="dateB">起始日期</param>
        /// <param name="dateE">结束日期</param>
        /// <param name="state">订单状态</param>
        /// <returns></returns>
        public List<Billinfo> Query(int billType, long clientId, int storageId, string goodsName,
                                     long busiuserId, long curphaseuserId, long createuserId,
                                     string billNo, string note2, DateTime dateB, DateTime dateE, int state)
        {
            var sql = string.Format(@" BILLTYPE = {0} AND ( {1} = 0 OR CLIENTID={1} ) 
                                       AND ( {2} =0 OR STORAGEID={2} ) 
                                       AND ('{3}'='' OR SUMMARY like '%{3}%' )
                                       AND ( {4} = 0 OR BUSIUSERID={4} ) 
                                       AND ( {5} = 0 OR CURPHASEUSERID={5} )
                                       AND ( {6} = 0 OR CREATEUSERID={6} )  
                                       AND ('{7}'='' OR BILLNO like '%{7}%' ) 
                                       AND ('{8}'='' OR NOTE2 like '%{8}%' )
                                       AND ('{9}'<= CONVERT(varchar(10),BILLDATE,120) 
                                       AND  '{10}'>=CONVERT(varchar(10),BILLDATE,120) )
                                       AND ( {11} = -1 OR STATE = {11} )"
                                      , billType, clientId, storageId, goodsName, busiuserId, curphaseuserId
                                      , createuserId, billNo, note2, dateB.ToString("yyyy-MM-dd"), dateE.ToString("yyyy-MM-dd"), state);

            var list = this.DbSession.Query<Billinfo>(sql).ToList();

            list.ForEach(ValueToName);

            return list;
        }

        /// <summary>
        /// 单据信息查询
        /// </summary>
        /// <param name="billNo">订单编号</param>
        /// <param name="billType">单据类型</param>
        /// <returns></returns>
        public Billinfo Get(string billNo, int billType)
        {
             var o= DbSession.Query<Billinfo>("BILLNO=@0 AND BILLTYPE=@1", billNo, billType).FirstOrDefault();    

            if (o == null) return o;
            ValueToName(o);
            return o;
        }

        /// <summary>
        /// 单据信息
        /// </summary>
        /// <param name="id">订单信息ID</param>
        /// <param name="billType">单据类型</param>
        /// <returns></returns>
        public Billinfo Get(long id, int billType)
        {
            var sql = string.Format(@" ID = {0} AND BILLTYPE = {1} ", id, billType);

            var o = DbSession.Query<Billinfo>(sql).FirstOrDefault();

            if (o == null) return o;

            ValueToName(o);

            return o;
        }

        protected void ValueToName(Billinfo o)
        {
            o.ListBilldetail = DbSession.Query<Billdetail>("BILLID=@0", o.Id).ToList();

            var bill = new BilltypeinfoBLL();
            var client = new ClientinfoBLL();
            var store = new StorageinfoBLL();
            var user = new UserinfoBLL();
            var dic = new SysdictableBLL();
            var dept = new DeptinfoBLL();

            var objBill = bill.Get(long.Parse(o.Billtype.Value.ToString()));
            if (objBill != null) o.BilltypeName = objBill.Billname;

            if (o.Clientid != null)
            {
                var objClient = client.Get(o.Clientid.Value);
                if (objClient != null) o.ClientName = objClient.Clientname;
            }

            var objStore = store.Get(o.Storageid.Value);
            if (objStore != null) o.StorageName = objStore.Stoname;

            if (o.Storageid2 != null)
            {
                var objStore2 = store.Get(o.Storageid2.Value);
                if (objStore2 != null) o.StorageName2 = objStore2.Stoname;
            }

            if (o.Deptid != null)
            {
                var objDeptid = dept.Get(o.Deptid.Value);
                if (objDeptid != null) o.DeptName = objDeptid.Deptname;
            }

            if (o.Invoicetype != null)
            {
                var objDic = dic.Get(o.Invoicetype.Value);
                if (objDic != null) o.InvoicetypeName = objDic.Dicname;
            }

            if (o.Busiuserid != null)
            {
                var objUser = user.Get(o.Busiuserid.Value);
                if (objUser != null) o.BusiuserName = objUser.Username;
            }

            if (o.Curphaseuserid != null)
            {
                var objUser = user.Get(o.Curphaseuserid.Value);
                if (objUser != null) o.CurphaseuserName = objUser.Username;
            }

            if (o.Createuserid != null)
            {
                var objUser = user.Get(o.Createuserid.Value);
                if (objUser != null) o.CreateuserName = objUser.Username;
            }

            o.StateName = ((BillStateEnum)o.State.Value).ToString();
        }

        /// <summary>
        /// 单据信息
        /// </summary>
        /// <param name="billType">单据类型</param>
        /// <returns></returns>
        public long Get(int billType)
        {
            var dt = DbSession.ExcuteQuery(string.Format("select MIN(ID) as ID from dbo.BILLINFO where BILLTYPE={0}", billType));

            return dt != null ? Normal.ToLong(dt.Rows[0][0]) : 0;
        }

        /// <summary>
        /// 编辑单据信息
        /// </summary>
        /// <param name="o"></param>
        public Billinfo Edit(Billinfo o)
        {
            if (o.Id == 0)
            {
                var objBill = new BilltypeinfoBLL();
                var bill = objBill.Get(o.Billtype.Value);

                o.Billno = FormatData(bill);
               
                this.DbSession.Insert(o, "Id", "ListBilldetail", "BilltypeName", "DeptName", "ClientName",
                                         "BusiuserName", "StorageName", "StorageName2", "CreateuserName",
                                         "StateName", "CurphaseuserName", "InvoicetypeName");

                o.Id = Get(o.Billno, o.Billtype.Value).Id;

                if (o.ListBilldetail != null)
                {
                    o.ListBilldetail.ForEach(r =>
                    {
                        r.Billid = o.Id;
                        this.DbSession.Insert(r, "Id", "Flag");
                    });
                }

                var b = DateTime.Now.Day.Equals(1) || bill.Maxdate == null || !DateTime.Now.Month.Equals(bill.Maxdate.Value.Month);
                bill.Maxbillno = b ? 1 : bill.Maxbillno + 1;
                bill.Maxdate = DateTime.Now;

                objBill.Edit(bill);
            }
            else
            {
                this.DbSession.Update(o);
                if (o.ListBilldetail != null)
                {
                    o.ListBilldetail.ForEach(r =>
                    {
                        r.Billid = o.Id;
                        if (r.Id == 0)
                            DbSession.Insert(r, "Id", "Flag");
                        else
                        {
                            if (r.Flag == 0)
                                DbSession.Update(r);
                            else
                                DbSession.Delete<Billdetail>(r.Id);
                        }
                    });
                }
               
            }
            this.DbSession.Commit();
            //调采购订单时，更新采购订单明细收、欠数量
            if (o.Billtype == 2 && o.Note.StartsWith("调"))
            {
                UpdatePurchaseAmount(o.Note);
               
            }
            //收货单一级审核通过时，判断订单是否执行完
            if (o.Billtype == 2 && o.Curphasename == "一级审核" && o.OrderID>0 && PurchaseBillIsFinished(o.Note))
            {
                OrderinfoBLL _orderbll=new OrderinfoBLL();
                Orderinfo _order = _orderbll.Get(o.OrderID, 1);
                if (_order != null)
                {
                    _order.Exestate =(int?)BillExuStateEnum.已完成;
                    _orderbll.Edit(_order);
                }
            }
           

            return o;
        }
        /// <summary>
        /// 更新采购订单收货信息
        /// </summary>
        /// <param name="orderno"></param>
        void UpdatePurchaseAmount(string orderno)
        {
            if (orderno == null || orderno.Trim() == "")
                return;            

            //select OrderNo,OrderID,GoodsID,SUM(OrderNum) OrderNum,SUM(ReceiveNum) ReceiveNum from [dbo].view_OrderPurchase
            //group by orderno,orderid,goodsid
            //order by orderno,orderid,goodsid

             string sql = string.Format(@"select Orderno,Note,Orderid,Goodsid,OrderNum,ReceiveNum,ReturnNum from [dbo].view_OrderPurchase Where Note={0}", "'" + orderno + "'");
            System.Data.DataTable dt=this.DbSession.ExcuteQuery(sql);
          
            if (dt == null)
                return;
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                  sql = string.Format(@"update [db_pydcncom].[dbo].ORDERDETAIL set RECEIVENUM={0},NORECIVENUM={1},RECEIVEMONEY={2}
                  where ORDERID={3} and GOODSID={4}", dt.Rows[i]["ReceiveNum"].ToString()+"-"+ dt.Rows[i]["ReceiveNum"].ToString(), "NUM-" + dt.Rows[i]["ReceiveNum"].ToString() + "+" + dt.Rows[i]["ReturnNum"].ToString(), "UNITPRICE*" + dt.Rows[i]["ReceiveNum"].ToString(),
                                                    dt.Rows[i]["Orderid"].ToString(), dt.Rows[i]["Goodsid"].ToString());
                this.DbSession.ExcuteNonQuery(sql);
            }
        }

        /// <summary>
        /// 检查采购订单所有明细项是否收货完成
        /// </summary>
        /// <param name="orderno"></param>
        bool PurchaseBillIsFinished(string orderno)
        {
            if (orderno == null || orderno.Trim() == "")
                return false;
            string sql = string.Format(@"select Orderno,Note,Orderid,Goodsid,OrderNum,ReceiveNum,ReturnNum from [dbo].view_OrderPurchase Where Note={0} and OrderNum+ReturnNum>ReceiveNum", "'" + orderno + "'");
            System.Data.DataTable dt=this.DbSession.ExcuteQuery(sql);
          
            if (dt == null)
                return false;
            return dt.Rows.Count < 1 ? true : false;           
        }
     
        /// <summary>
        /// 
        /// </summary>
        /// <param name="bill">单据类型</param>
        /// <returns></returns>
        string FormatData(Billtypeinfo bill)
        {
            string dateFormat;
            var date = DateTime.Now;
            switch (bill.Codedate)
            {
                case "YYYY-MM-DD": dateFormat = date.ToString("yyyy-MM-dd"); break;
                case "YYYYMMDD": dateFormat = date.ToString("yyyyMMdd"); break;
                case "YYYY年MM月DD日": dateFormat = date.ToString("yyyy年MM月dd日"); break;
                case "MM-DD": dateFormat = date.ToString("MM-dd"); break;
                case "MMDD": dateFormat = date.ToString("MMdd"); break;
                case "MM月DD日": dateFormat = date.ToString("MM月dd日"); break;
                case "YYYY-MM": dateFormat = date.ToString("yyyy-MM"); break;
                case "YYYYMM": dateFormat = date.ToString("yyyyMM"); break;
                case "YYYY年MM月": dateFormat = date.ToString("yyyy年MM月"); break;
                case "YYYY": dateFormat = date.ToString("yyyy"); break;
                case "YYYY年": dateFormat = date.ToString("yyyy年"); break;
                default: dateFormat = "-"; break;
            }

            var b = DateTime.Now.Day.Equals(1) || bill.Maxdate == null || !DateTime.Now.Month.Equals(bill.Maxdate.Value.Month);
            var max = b ? 0 : bill.Maxbillno.Value;
            var noLengh = bill.Codesno.Length - (max + 1).ToString().Length;
            var strTemp = "";
            for (var i = 0; i < noLengh; i++)
                strTemp += "0";

            return string.Format("{0}{1}{2}{3}{4}", bill.Codepre, bill.Codesep1, dateFormat, bill.Codesep2, string.Format("{0}{1}", strTemp, max + 1));
        }

        /// <summary>
        /// 删除订单信息
        /// </summary>
        /// <param name="id"></param>
        public void Delete(long id)
        {
            DbSession.Delete<Billinfo>(id);
        }

        /// <summary>
        /// 浏览记录 上一条 下一条
        /// </summary>
        /// <param name="id">浏览记录Id</param>
        /// <param name="type">类型 0-向上,1-向下</param>
        /// <param name="billtype">单据类型</param>
        /// <param name="isLast">是否最后一条数据</param>
        /// <returns></returns>
        public Billinfo PreRecord(long id, int type, int billtype, ref bool isLast)
        {
            var obj = Get(id, billtype);
            if (obj == null)
            {
                var dt = DbSession.ExcuteQuery(string.Format("select {0}(ID) as ID from dbo.Billinfo where BILLTYPE = {1}", type.Equals(0) ? "MIN" : "MAX", billtype));
                var lId = dt.Rows.Count > 0 ? Normal.ToLong(dt.Rows[0][0]) : 0;

                isLast = type.Equals(0) ? id <= lId + 1 : id >= lId - 1;

                var list = DbSession.SqlQuery<Billinfo>(
                    string.Format("select top 1 * from dbo.Billinfo where ID {1} {0} and BILLTYPE = {3} Order by Id {2}",
                    isLast ? lId + (type.Equals(0) ? 1 : -1) : id, type.Equals(0) ? "<" : ">", type.Equals(0) ? "desc" : "asc", billtype));

                obj = list.First();

                ValueToName(obj);
            }

            return obj;
        }

    }
}
